# -*- coding = utf-8 -*-
# name   : 删除历史数据 v2
# Author : admin
# Email  : 
# File   : delete_historical_data_v2.py
# Ver    : 1.0
# Time   : 2025-07-14 11:51
import os
import time

from utils.log_config import logging

from datetime import datetime, timedelta
from apscheduler.schedulers.blocking import BlockingScheduler

from config import current_env
from addon.delete_historical_data.batch_delete_data import batch_delete
from addon.delete_historical_data.table_name import delete_conf



# 写入日志到文件并自动管理文件大小
def write_log(message, log_file='app_tips.log', max_size=104857600, backup_count=3):
    """
    写入日志到文件并自动管理文件大小

    参数：
    message: 要写入的日志内容（字符串）
    log_file: 日志文件路径（默认：当前目录下的app.log）
    max_size: 最大文件大小（字节，默认100MB=104857600字节）
    backup_count: 最大备份文件数量（默认保留3个备份）
    """
    # 定义日志文件路径
    log_dir = "logs"
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)  # 创建日志目录
    log_file = os.path.join(log_dir, log_file)  # 合并日志目录和文件名

    # 检查日志文件是否存在且是否超过大小限制
    if os.path.exists(log_file):
        file_size = os.path.getsize(log_file)  # 获取当前文件大小
        if file_size > max_size:  # 超过阈值时执行备份操作
            # 从最新的备份开始向后轮转（保持备份数量不超过指定值）
            # 例如 backup_count=3 时，循环范围是 2,1（因为range是左闭右开）
            for i in range(backup_count - 1, 0, -1):
                src = f"{log_file}.{i}"  # 当前备份文件路径（如 app.log.2）
                # 计算下一个备份位置（最后一个备份直接命名为.bak）
                dst = f"{log_file}.{i + 1}" if i != backup_count - 1 else f"{log_file}.bak"

                # 新增安全处理：如果目标文件存在则先删除
                if os.path.exists(dst):
                    os.remove(dst)  # 删除可能存在的旧备份

                # 如果源文件存在则执行重命名（避免覆盖旧备份）
                if os.path.exists(src):
                    os.rename(src, dst)

            # 处理第一个备份位置（将当前文件备份为.1）
            # 先删除可能存在的旧.1文件（防止残留）
            if os.path.exists(f"{log_file}.1"):
                os.remove(f"{log_file}.1")
            # 将当前日志文件重命名为.1备份
            os.rename(log_file, f"{log_file}.1")

    # 以追加模式打开日志文件（保证线程安全）
    with open(log_file, 'a', encoding='utf-8') as f:
        # 获取格式化后的当前时间戳
        timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
        # 写入格式化后的日志条目（包含时间戳）
        f.write(f"[{timestamp}] {message}\n")


# 删除指定集合中指定时间之前的数据
def delete_historical_data(config: dict):
    """
    删除指定集合中指定时间之前的数据

    :return:
    """
    db_mongo = config.get("db_mongo")
    collection_name = config.get("collection_name")
    days = config.get("days")
    date_lie = config.get("date_lie", "create_time")
    task_name = config.get("name")
    one_day = config.get("one_day", False)

    # 删除条数
    delete_count, duration_all = batch_delete(db_mongo, table_name=collection_name, days=days, date_lie=date_lie,
                                              one_day=one_day)

    # 聚合查询
    aggregate_query = [
        {
            "$group": {
                "_id": "null",
                "count": {
                    "$sum": 1
                }
            }
        }
    ]

    res1 = list(db_mongo[collection_name].aggregate(aggregate_query))
    # 剩余数据条数
    res_count = 0
    if len(res1) > 0:
        # 剩余数据条数
        res_count = list(res1)[0]['count']

    msg = f"[{task_name}] {collection_name} 集合删除[{days}]天之前的数据[{delete_count}]条；剩余[{res_count}]条数据, 耗时: {duration_all:.2f} 秒."
    logging.info(msg)
    write_log(msg)


# 开始任务
def start_task():

    # 遍历配置
    for key, value in delete_conf.items():
        # task_code = key
        task_name = value.get("name")
        mongo_obj = value.get("mongo_obj")
        db_mongo = value.get("db_mongo")
        table_names = value.get("table_names")
        status = value.get("status", False)

        if status:
            for table_name, days, date_lie in table_names:
                temp_dict = {
                    'db_mongo': db_mongo,
                    'collection_name': table_name,
                    'days': days,
                    'date_lie': date_lie,
                    'name': task_name,
                    'one_day': value.get("one_day", False)
                }
                # print(temp_dict)

                delete_historical_data(temp_dict)

        mongo_obj.close()


# 定时执行|马上执行
def main():
    if current_env in ['test', 'production']:
        logging.info("**生产环境 定时任务 执行** start")
        scheduler = BlockingScheduler(timezone="Asia/Shanghai")

        # 每天凌晨2点30分执行一次
        scheduler.add_job(start_task, 'cron', hour=2, minute=30, next_run_time=(datetime.now() + timedelta(seconds=5)),
                          jitter=3)

        # 启动任务
        scheduler.start()
    else:
        logging.info("**开发环境 直接执行** start")
        start_task()


if __name__ == '__main__':
    start_task()
